package cn.stylefeng.guns.modular.gridsystem.api.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.pojo.base.param.BaseParam;
import cn.stylefeng.guns.core.pojo.response.ResponseData;
import cn.stylefeng.guns.core.pojo.response.SuccessResponseData;
import cn.stylefeng.guns.modular.gridsystem.constants.GatewayTypeCodeConstant;
import cn.stylefeng.guns.modular.gridsystem.constants.UplaodFolderConstant;
import cn.stylefeng.guns.modular.gridsystem.entity.*;
import cn.stylefeng.guns.modular.gridsystem.model.param.*;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizDeviceExceptionRecordResult;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizExceptionResult;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizGatewayChannelResult;
import cn.stylefeng.guns.modular.gridsystem.service.*;
import cn.stylefeng.guns.modular.gridsystem.utils.MyConst;
import cn.stylefeng.guns.sys.modular.file.service.SysFileInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

/**
 * 采集端接口控制器
 *
 * @author zxw 2022/12/17 15:01
 */
@RestController
@RequestMapping("/v2/api/collection")
@RequiredArgsConstructor
@Slf4j
public class CollectionApiController {

    private final CollectionFaultService collectionFaultService;

    private final GatewayFLowService gatewayFLowService;

    private final SysFileInfoService sysFileInfoService;

    private final BizGatewayService bizGatewayService;

    private final BizFosInfoService bizFosInfoService;

    private final BizGatewayChannelService bizGatewayChannelService;

    private final BizAmpLogService bizAmpLogService;

    private final BizChannelTypeService channelTypeService;
    private final BizExceptionService bizExceptionService;
    private final BizDeviceService bizDeviceService;
    private final BizStationService bizStationService;
    private final BizDeviceStatusAssessService bizDeviceStatusAssessService;
    private final BizDeviceStatusAssessInfoService bizDeviceStatusAssessInfoService;

    /**
     * 上报故障
     */
    @PostMapping("/reportFault")
    public ResponseData reportFault(@Validated(CollectionFaultParam.reportFault.class) CollectionFaultParam param) {
        collectionFaultService.reportFault(param);
        return new SuccessResponseData();
    }

    /**
     * 上报流量
     */
    @PostMapping("/reportFlow")
    public ResponseData reportFlow(@Validated(BaseParam.add.class) GatewayFlowParam param) {
        gatewayFLowService.add(param);
        return new SuccessResponseData();
    }

    /**
     * 上报光纤传感器信息
     * @param gatewayCode
     * @return
     */
    @PostMapping("/reportChannelInfoByFos")
    public ResponseData reportChannelInfo(@RequestParam String gatewayCode) {
        //查询网关
        final BizGateway bizGateway = bizGatewayService.listByDeviceCode(gatewayCode);
        if (ObjectUtil.isNull(bizGateway)) {
            throw new ServiceException(MyConst.GATEWAY_NOT_EXIST);
        }

        final BizChannelType channelType = channelTypeService.getOne(new LambdaQueryWrapper<BizChannelType>().eq(BizChannelType::getCode, GatewayTypeCodeConstant.FIBRE_OPTICAL_SENSORS_CODE));

        if(ObjectUtil.isNull(channelType)){
            throw new ServiceException("未查询到"+GatewayTypeCodeConstant.FIBRE_OPTICAL_SENSORS_CODE + "的通道信息");
        }

        BizGatewayChannelParam channelParam = new BizGatewayChannelParam();
        channelParam.setGatewayId(bizGateway.getId());
        channelParam.setChannelType(channelType.getId());
        List<BizGatewayChannelResult> channelResultList = bizGatewayChannelService.listByGId(channelParam);
        log.info("通道列表：{}",channelResultList);
        return new SuccessResponseData(channelResultList);
    }


    /**
     * 上报光纤振幅日志
     *
     * @param gatewayCode
     * @return
     */
    @PostMapping("/reportAmpLog")
    public ResponseData reportAmpLog(@RequestPart(value = "file") MultipartFile file, @RequestParam String gatewayCode, @RequestParam String vibrationPoint) {
        //查询网关
        final BizGateway bizGateway = bizGatewayService.listByDeviceCode(gatewayCode);
        if (ObjectUtil.isNull(bizGateway)) {
            throw new ServiceException(MyConst.GATEWAY_NOT_EXIST);
        }

        //接收文件
        String path = UplaodFolderConstant.FOS_AMP_FOLDER + "/" + bizGateway.getGatewayCode() + "/" + DateUtil.format(new Date(), "yyyyMMdd");
        Long fileId = sysFileInfoService.uploadFile(file, path, file.getOriginalFilename());

        BizGatewayChannelParam channelParam = new BizGatewayChannelParam();
        channelParam.setGatewayId(bizGateway.getId());
        List<BizGatewayChannelResult> channelResultList = bizGatewayChannelService.listChannel(channelParam);
        Optional<BizGatewayChannelResult> bizGatewayChannelResult = channelResultList.stream().filter(channelResult -> {
                    Integer channelResultId = channelResult.getId();
                    BizFosInfo fosInfo = bizFosInfoService.getOne(new LambdaQueryWrapper<BizFosInfo>().eq(BizFosInfo::getChannelId, channelResultId));
                    if (ObjectUtil.isNull(fosInfo)) {
                        return false;
                    }

                    String startPoint = fosInfo.getStartPoint();
                    String endPoint = fosInfo.getEndPoint();

                    if (ObjectUtil.isEmpty(startPoint) || ObjectUtil.isEmpty(endPoint)) {
                        return false;
                    }
                    return ObjectUtil.compare(vibrationPoint, startPoint) > 0 && ObjectUtil.compare(vibrationPoint, endPoint) < 0;
                }
        ).findFirst();

        bizGatewayChannelResult.ifPresent(gatewayChannelResult -> {
            BizAmpLogParam ampLogParam = new BizAmpLogParam();
            ampLogParam.setGatewayCode(gatewayCode);
            ampLogParam.setFileId(fileId);
            ampLogParam.setVibrationPoint(vibrationPoint);
            ampLogParam.setChannel(gatewayChannelResult.getChannel());
            bizAmpLogService.add(ampLogParam);
        });

        return new SuccessResponseData();
    }

    @PostMapping("/reportDeviceStatusLog")
    public ResponseData reportDeviceStatusLog(){

        DateTime dateTime = DateUtil.lastMonth();
        String startTime = DateUtil.formatDateTime(DateUtil.beginOfMonth(dateTime));
        String endTime = DateUtil.formatDateTime(DateUtil.endOfMonth(dateTime));

        List<BizStation> list = bizStationService.list();
        for (BizStation station : list){
            Integer id = station.getId();
            List<BizDeviceExceptionRecordResult> recordResults = bizDeviceService.getDeviceException(id,startTime,endTime);
            for (BizDeviceExceptionRecordResult result:recordResults){
                BizDeviceStatusAssessParam param = new BizDeviceStatusAssessParam();
                param.setDeviceId(result.getDeviceId());
                param.setErrorNumber(result.getUnprocessedRecords());
                param.setNormalNumber(result.getProcessedRecords());
                param.setAssessTime(DateUtil.date());
                param.setType(1);
                Integer assessId = bizDeviceStatusAssessService.add(param);
                Integer deviceId = result.getDeviceId();
                List<BizExceptionResult> results = bizExceptionService.getDeviceExceptionList(station.getId(),deviceId,startTime,endTime);
                Set<Integer> integers = new HashSet<>();
                for (BizExceptionResult exceptionResult : results){
                    Integer exceptionId = exceptionResult.getExceptionId();
                    integers.add(exceptionId);
                }
                BizDeviceStatusAssessInfo assessInfo = new BizDeviceStatusAssessInfo();
                assessInfo.setAssessId(assessId);
                assessInfo.setExceptionIds(integers.toString());
                bizDeviceStatusAssessInfoService.save(assessInfo);
            }
        }
        return new SuccessResponseData();
    }

}
